package com.midian.service.user.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.midian.common.dao.BaseDaoBySql;
import com.midian.common.dao.BaseDaoTemplet;
import com.midian.common.dao.OrderHelper;
import com.midian.common.dao.SearchHelper;
import com.midian.common.dao.SearchHelper.Type;
import com.midian.common.exception.BizException;
import com.midian.common.pager.Pager;
import com.midian.common.system.SysStatic;
import com.midian.common.utils.StringUtil;
import com.midian.model.permission.Auth;
import com.midian.model.permission.Role;
import com.midian.model.permission.RoleUser;
import com.midian.model.user.User;
import com.midian.model.user.vo.UserInfoVo;
import com.midian.service.common.BaseService;
import com.midian.service.device.IDeviceService;
import com.midian.service.user.IUserService;
/**
 * 用户业务实现类
 * @author 飞
 *
 */
@Service("userService")
public class UserServiceImpl extends BaseService implements IUserService {

	/**用户DAO*/
	private BaseDaoBySql<User> userDAO;
	
	/**角色用户DAO*/
	private BaseDaoTemplet<RoleUser> roleUserDAO;
	/**设备业务*/
	private IDeviceService deviceService;
	
	@Resource(name = "userDAO")
	public void setUserDAO(BaseDaoBySql<User> userDAO) {
		this.userDAO = userDAO;
	}
	
	@Resource(name = "roleUserDAO")
	public void setRoleUserDAO(BaseDaoTemplet<RoleUser> roleUserDAO) {
		this.roleUserDAO = roleUserDAO;
	}
	@Resource(name="deviceService")
	public void setDeviceService(IDeviceService deviceService) {
		this.deviceService = deviceService;
	}
	@Override
	public User add(User target) throws BizException {
		if(StringUtils.isNotBlank(target.getPassword())) {
			target.setPassword(StringUtil.generatePassword(target.getPassword())); //MD5加密
		}
		
		this.userDAO.add(target);
		//处理用户与角色的关系绑定
		opRoleUser(target);
		return target;
	}

	@Override
	public void update(User target) throws BizException {
		if(StringUtils.isNotBlank(target.getPassword())) {
			target.setPassword(StringUtil.generatePassword(target.getPassword())); //MD5加密
		}
		StringBuilder hql = new StringBuilder("update User o set o.account = ?");
		ArrayList<Object> valuesArr = new ArrayList<Object>();
		valuesArr.add(target.getAccount());
		if(StringUtils.isNotBlank(target.getPassword())){//销售员或者管理者更改
			hql.append(",o.password = ?");
			valuesArr.add(target.getPassword());
		}
		if(StringUtils.isNotBlank(target.getName())){
			hql.append(",o.name = ?");
			valuesArr.add(target.getName());
		}
		if(target.getSex()!=null&&target.getSex()>0){
			hql.append(",o.sex = ?");
			valuesArr.add(target.getSex());
		}
		if(StringUtils.isNotBlank(target.getPhone())){
			hql.append(",o.phone = ?");
			valuesArr.add(target.getPhone());
		}
		if(target.getIsAdmin()!=null&&target.getIsAdmin()>0){
			hql.append(",o.isAdmin = ?");
			valuesArr.add(target.getIsAdmin());
		}
		if(target.getHeadPicId() != null && StringUtils.isNotBlank(target.getHeadPicId().getId())){
			hql.append(",o.headPicId.id = ?");
			valuesArr.add(target.getHeadPicId().getId());
		}
		hql.append(" where o.id = ?");
		valuesArr.add(target.getId());
		this.userDAO.update(hql.toString(), valuesArr.toArray());
		//先删除原来用户所绑定的角色
		String hql1 = "delete from RoleUser o where o.user.id = ?";
		this.roleUserDAO.update(hql1, new Object[]{target.getId()});
		//处理用户与角色的关系绑定
		opRoleUser(target);
	}
	@Override
	public void delete(Serializable id) throws BizException {
		this.userDAO.delete(id);
	}

	@Override
	public void delete(Serializable[] ids) throws BizException {
		this.userDAO.delete(ids);
	}

	@Override
	public User get(Serializable id) throws BizException {
		String hql="from User o left join fetch o.headPicId where o.id=?";
		return (User)this.userDAO.findObject(hql, new Object[]{id});
	}

	@Override
	public List<User> showList(User target, Pager pager,
			List<OrderHelper> helper) throws BizException {
//		Integer vipIndex = null; //是否vip排序列下标
//		for(int i = 0; i < helper.size(); i++) {
//			if("o.isVip".equals(helper.get(i).getPropertyName())) {
//				vipIndex = i;
//			}
//		}
//		//如果设置了按是否VIP排序，先排企业在前，再排会员在后
//		if(vipIndex != null) {
//			if(vipIndex > 0) {
//				vipIndex--;
//			}
//			helper.add(vipIndex, new OrderHelper("identity", OrderHelper.Type.DESC));
//		}
		
		return this.userDAO.find(target, getSearchHelper(), helper, pager);
	}

	@Override
	public void opDelFlag(Serializable[] ids, Integer status) throws BizException {
		this.userDAO.opDelFlag(ids, status);
		//如果是禁用会员的情况，更新会员的token
		if(SysStatic.DELFLAG.equals(status)) {
			for (Serializable userId : ids) {
				//升级VIP后，更新用户的token
				updateUserToken(userId);
			}
		}
	}

	@Override
	protected List<SearchHelper> getSearchHelper() {
		String[] attrs = {"headPicId", "account", "name","phone","sex", "isAdmin", "identity", "userfrom","delFlag"};
		Type[] types = {Type.LEFTFETCH, Type.LIKE,Type.LIKE, Type.LIKE, Type.EQ, Type.EQ, Type.EQ, Type.EQ, Type.EQ};
		return SearchHelper.getSearchList(attrs, types);
	}

	@Override
	public User getUserByAccessToken(String access_token, Integer userId) {
		String hql="from User where accessToken = ? and id = ?";
		return (User)this.userDAO.findObject(hql, new Object[]{access_token,userId});
	}

	@Override
	public User getUserByAccount(String account, String userId) {
		ArrayList<Object> valuesArr = new ArrayList<Object>();
		String hql;
		if(StringUtils.isNotBlank(userId)){//编辑状态,验证唯一性要去除自身
			hql="from User where account =? and id!=?";
			valuesArr.add(account);
			valuesArr.add(userId);
		}else{
			hql="from User where account =?";
			valuesArr.add(account);
		}
		return (User)this.userDAO.findObject(hql,valuesArr.toArray());
	}
		
		
	

	@Override
	public void updatePasswordByAccount(String account, String password)
			throws BizException {
		String hql="update User set password=? where account=?";
		this.userDAO.update(hql, new Object[]{password,account});
	}

	/**
	 * 处理用户与角色的关系绑定
	 * @param target
	 */
	private void opRoleUser(User target) {
		//用户绑定的角色id列表
		List<String> roleIdList = target.getRoleIdList();
		//如果用户有绑定角色，进行用户与角色关系的保存
		if(roleIdList != null && !roleIdList.isEmpty()) {
			String userId = target.getId(); //用户id
			for (String roleId : roleIdList) {
				RoleUser roleUser = new RoleUser();
				//用户对象
				User users = new User();
				users.setId(userId); //设置用户id
				//角色对象
				Role role = new Role();
				role.setId(roleId); //设置角色id
				roleUser.setUser(users); //设置用户对象
				roleUser.setRole(role); //设置角色对象
				this.roleUserDAO.add(roleUser);
			}
		}
	}
	
	/**
	 * 登录
	 * @param entity 用户对象
	 * @return 返回用户VO对象
	 */
	@Override
	public UserInfoVo login(User entity) throws BizException {
		String[] attrs = {"account", "password"};
		Type[] types = {Type.EQ, Type.EQ};
		if(StringUtils.isNotBlank(entity.getPassword())) {
			entity.setPassword(StringUtil.generatePassword(entity.getPassword())); //MD5加密
		}
		User user = this.userDAO.findObject(entity, SearchHelper.getSearchList(attrs, types)); //获取用户对象
		if(user == null) {
			throw new BizException("用户名或密码不正确");
		}
		UserInfoVo userInfoVo = new UserInfoVo();
		BeanUtils.copyProperties(user, userInfoVo);
		//获取用户的权限列表
		List<Auth> authList = this.getUserAuthList(userInfoVo.getId());
		//用户权限集（key：权限id，value：权限key）
		Map<String, String> authMap = userInfoVo.getAuthMap();
		for (Auth auth : authList) {
			authMap.put(auth.getId(), auth.getKeyName());
		}
		return userInfoVo;
	}
	
	/**
	 * 根据用户id，获取用户的角色id列表
	 * @param userId 用户id
	 * @return
	 * @throws BizException
	 */
	@Override
	public List<String> getRoleIdListByUserId(String userId) throws BizException {
		String hql = "select o.role.id from RoleUser o where o.user.id = ?";
		return this.roleUserDAO.find(hql, new Object[]{userId});
	}
	
	/**
	 * 获取用户权限列表
	 * @param userId 用户id
	 * @return
	 * @throws BizException
	 */
	private List<Auth> getUserAuthList(String userId) throws BizException {
		StringBuilder sb = new StringBuilder();
		List<Object> valueList = new ArrayList<Object>();
		sb.append("select a.* from role_users rs")
		  .append(" inner join role_auth ra on rs.roleId = ra.roleId ")
		  .append(" inner join auth a on ra.authId = a.id")
		  .append(" where rs.userId = ? and a.deleteFlag = ?");
		valueList.add(userId);
		valueList.add(SysStatic.NORMALDELFLAG);
		return this.userDAO.findBySql(sb.toString(), valueList.toArray(), Auth.class);
	}
	
	/**
	 * 更新用户的token
	 * @param userId 用户id
	 * @throws BizException
	 */
	private void updateUserToken(Serializable userId) throws BizException {
		User user = get(userId);
		if(user != null) {
			String token = "";
			//非第三方登录会员，更新与账号有关的token
			if(IUserService.USER_FROM_NORMAL.equals(user.getUserfrom())) {
				token = StringUtil.generateToken(user.getAccount());
			} else {
			//第三方登录会员，更新token
				token = StringUtil.generateToken();
			}
			//如果审核通过，更新用户对象的身份为企业
			String hql = "update User o set o.token = ?, o.tokenTime = ? where o.id = ?";
			this.userDAO.update(hql, new Object[]{token, new Date(), user.getId()});
		}
	}

	@Override
	public List<User> getUsers() throws BizException {
		String hql = "from User t where t.delFlag = ?";
		return  this.userDAO.find(hql, new Object[]{SysStatic.NORMALDELFLAG});
	}
}
